/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lightsh.widget.animation;

import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.graphics.Camera;
import android.graphics.Matrix;

/**
 * 根据一个特定的角度，实现以Y轴为轴旋转的动画效果。并且，通过对z轴的移动增加3d效果。
 * @author Shu
 */
public class Rotate3dAnimation extends Animation {
    private final float mFromDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthZ;
    private final boolean mReverse;
    private Camera mCamera;

    /**
     * 
     * 创建一个3d的动画animation对象。旋转的角度由fromDegrees和toDegrees定义。旋转的中心点有2d的一个(x,y)点设置。
     * 旋转开始时，z轴会进行一定的移动，目的是增加3d的效果。
     *
     * @param fromDegrees 开始旋转的角度
     * @param toDegrees 结束旋转的角度
     * @param centerX 旋转的x轴中心点
     * @param centerY 旋转的y轴中心点
     * @param reverse 如果需要进行反方向的旋转则传入true，否则false(这里是是否进行view从小到大的转换)
     */
    public Rotate3dAnimation(float fromDegrees, float toDegrees,
            float centerX, float centerY, float depthZ, boolean reverse) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mDepthZ = depthZ;
        mReverse = reverse;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mCamera = new Camera();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float fromDegrees = mFromDegrees;
        
        // 计算当前需要显示的角度
        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;

        // 获取需要改变的matrix对象
        final Matrix matrix = t.getMatrix();

        camera.save();
        if (!mReverse) {
        	// z轴进行移动
            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
        } else {
        	// z轴进行移动
            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
        }
        camera.rotateY(degrees);
        
        // 将刚才的操作赋值到目标矩阵
        camera.getMatrix(matrix);
        camera.restore();

        // 在矩阵旋转转换前将中心点移到设置的原点
        matrix.preTranslate(-centerX, -centerY);
        // 在矩阵旋转转换后将中心点重新移动回原来的位置
        matrix.postTranslate(centerX, centerY);
    }
}
